<?php

/**
 * Description of BAWeBill
 * 这个CLASS用来处理买单交易。其结构基本为：
 * 1）定义买单交易的类型，比如餐馆买单。类型中可以定义一些类型所属的属性
 * 2）添加/修改/删除/查看 买单等，有管理员的操作，也有客户端的操作。管理员主要是买单结算等，客户主要是查看
 * 4）买单功能往往会调用一系列的其他功能，比如积分功能等，这个调用通常只需要执行其他COOKER里面的相应函数就可以了
 *
 * 如果想用APPCOMMON里面的ui，需要定义一个EVENT OF weBill"
 * 
 */
class BAWeBillCooker extends BAEventCooker {

    const BillType_All_Type = 'all_bill_type';

    //put your code here
    public function onShowBillTypeList($control = NULL) {
        //$opName = Blyn::app()->getActiveOperation()->getName();
        if (!$control instanceof BUIControl) {
            $control = $this->updateControl;
        }

        $eventHome = $this->getCurrentEventHome();
        $control->addRenderView('showTypeList', 'billType_list_' . $eventHome, array('billTypeList' => $this->getBillTypeList('arrayList')));
    }

    public function onShowAddBillType($data = NULL) {
        $typeId = $this->activeLink->getLinkVariable('billTypeId');

        $model = new BDynamicFormModel();
        $typeNameField = 'media_name_add_billType';
        $typeAliasField = 'media_alias_add_billType';
        $currencyField = 'media_currency_add_billType';
        $currencyUnitField = 'media_currencyUnit_add_billType';
        $discountRateField = 'media_discountRate_add_billType';

        $model->addField($typeNameField);
        $model->addField($typeAliasField);
        $model->addField($currencyField);
        $model->addField($currencyUnitField);
        $model->addField($discountRateField);

        //$typeTable = new BASpaceSheet('memberCardType', $this->getCurrentEvent());

        $type = NULL;
        if ($typeId != NULL && $typeId > 0) {

            $type = $this->getBillType($typeId);

            $typeAttributeTable = new BAAttributeSheet($type);

            $typeList = $typeAttributeTable->getList(array('itemData' => array('billTypeId' => $typeId)));

            //将已经存在的数据放进MODEL里面
            if ($typeList instanceof BTreeList) {
                if ($typeList->getItem('name') != NULL)
                    $model->$typeNameField = $typeList->getItem('name')->getValue();
                if ($typeList->getItem('alias') != NULL)
                    $model->$typeAliasField = $typeList->getItem('alias')->getValue();
                if ($typeList->getItem('currency') != NULL)
                    $model->$currencyField = $typeList->getItem('currency')->getValue();
                if ($typeList->getItem('currencyUnit') != NULL)
                    $model->$currencyUnitField = $typeList->getItem('currencyUnit')->getValue();
                if ($typeList->getItem('discountRate') != NULL)
                    $model->$discountRateField = $typeList->getItem('discountRate')->getValue();
            }
        }

        $this->updateControl->addRenderView('addBillType', 'billType_add', array(
            'model' => $model,
            'typeNameField' => $typeNameField,
            'typeAliasField' => $typeAliasField,
            'currencyField' => $currencyField,
            'currencyUnitField' => $currencyUnitField,
            'discountRateField' => $discountRateField,
            'billTypeId' => $typeId,
            'billType' => $type
        ));
    }

    public function onAddBillType($data = NULL) {
        $typeId = $this->activeLink->getLinkVariable('billTypeId');
        $mediaList = $this->postManager->populateMediaListFromPostData($this->postData, 'add_billType');

        $itemData = array();
        foreach ($mediaList as $media) {
            $name = $media->name;
            $value = $media->content;
            if ($value != NULL || $value != '') {
                $itemData[$name] = $value;
            }
        }

        $type = $this->addBillType($itemData['name'], $itemData['alias'], $itemData);

        $this->onShowBillTypeList();
    }

    public function onShowBillList($data = NULL) {
        $billType = $this->getCurrentBillType();
        $billTypeId = $billType->getId();

        $billView = $this->getBillList($billType);

        $opName = Blyn::app()->getActiveOperation()->getName();

        $this->updateControl->addRenderView('bill_list', 'bill_list_' . $opName, array(
            'billView' => $billView,
            'billType' => $billType,
            'billTypeId' => $billTypeId));
    }

    public function onShowAddBill($data = NULL) {

        $billId = $this->activeLink->getLinkVariable('billId');
        $billTable = new BASpaceSheet('bill');

        $model = new BDynamicFormModel();
        //$fixedCardIdField = 'media_fixedCardId_add_bill';
        //$mobileField = 'media_mobile_add_bill';
        $amountField = 'media_amount_add_bill';
        $seatField = 'media_seat_add_bill';
        $billTimeField = 'media_billTime_add_bill';
        $descriptionField = 'media_description_add_bill';

        //$model->addField($fixedCardIdField);
        //$model->addField($mobileField);
        $model->addField($amountField);
        $model->addField($seatField);
        $model->addField($billTimeField);
        $model->addField($descriptionField);

        if ($billId != NULL && $billId > 0) {

            $bill = $billTable->getListById($billId);

            //将已经存在的活动数据放进MODEL里面
            if ($bill->getItem('fixedCardId') != NULL)
                $model->$fixedCardIdField = $bill->getItem('fixedCardId')->getValue();
            if ($bill->getItem('mobile') != NULL)
                $model->$mobileField = $bill->getItem('mobile')->getValue();
            if ($bill->getItem('amount') != NULL)
                $model->$amountField = $bill->getItem('amount')->getValue();
            if ($bill->getItem('seat') != NULL)
                $model->$seatField = $bill->getItem('seat')->getValue();
            if ($bill->getItem('billTime') != NULL)
                $model->$billTimeField = $bill->getItem('billTime')->getValue();
            if ($bill->getItem('description') != NULL)
                $model->$descriptionField = $bill->getItem('description')->getValue();
        }else { //add a temporary card by userid_spaceid
            $bill = $billTable->getTempList();
        }

        $this->updateControl->addRenderView('billAdd', 'bill_add', array(
            'model' => $model,
            //'fixedCardIdField' => $fixedCardIdField,
            //'mobileField' => $mobileField,
            'amountField' => $amountField,
            'seatField' => $seatField,
            'billTimeField' => $billTimeField,
            'descriptionField' => $descriptionField,
            'bill' => $bill,
            'billId' => $bill->getId()));
    }

    public function onAddBill($data = NULL) {
        $billId = $this->activeLink->getLinkVariable('billId');

        $billTable = new BASpaceSheet('bill', $this->getCurrentBillType());

        $mediaList = $this->postManager->populateMediaListFromPostData($this->postData, 'add_bill');

        $itemData = array();
        foreach ($mediaList as $media) {
            $name = $media->name;
            $value = $media->content;
            $itemData[$name] = $value;
        }

        $bill = $this->addBill($itemData, $billId);

        $this->onShowBillList();
    }

    public function onShowBill($data = NULL) {
        $billId = $this->activeLink->getLinkVariable('billId');
        $billTable = new BASpaceSheet('bill');

//        $model = new BDynamicFormModel();
        $fixedCardIdField = '';
        $mobileField = '';
        $amountField = '';
        $seatField = '';
        $billTimeField = '';
        $descriptionField = '';
        $payAmount = '';

        //$model->addField($fixedCardIdField);
        //$model->addField($mobileField);
//        $model->addField($amountField);
//        $model->addField($seatField);
//        $model->addField($billTimeField);
//        $model->addField($descriptionField);

        if ($billId != NULL && $billId > 0) {

            $bill = $billTable->getListById($billId);

            //将已经存在的活动数据放进MODEL里面
            if ($bill->getItem('fixedCardId') != NULL)
                $fixedCardIdField = $bill->getItem('fixedCardId')->getValue();
            if ($bill->getItem('mobile') != NULL)
                $mobileField = $bill->getItem('mobile')->getValue();
            if ($bill->getItem('amount') != NULL)
                $amountField = $bill->getItem('amount')->getValue();
            if ($bill->getItem('seat') != NULL)
                $seatField = $bill->getItem('seat')->getValue();
            if ($bill->getItem('billTime') != NULL)
                $billTimeField = $bill->getItem('billTime')->getValue();
            if ($bill->getItem('payAmount') != NULL)
                $payAmount = $bill->getItem('payAmount')->getValue();
        }else { //add a temporary card by userid_spaceid
            $bill = $billTable->getTempList();
        }

        $this->updateControl->addRenderView('billAdd', 'bill_display', array(
//            'model' => $model,
            'fixedCardIdField' => $fixedCardIdField,
            'mobileField' => $mobileField,
            'amountField' => $amountField,
            'seatField' => $seatField,
            'billTimeField' => $billTimeField,
            'descriptionField' => $descriptionField,
            'payAmount' => $payAmount,
            'bill' => $bill,
            'billId' => $billId));
    }

    public function onShowAllTypeBill($data = NULL) {
        $billTypeList = $this->getBillTypeList();
        foreach ($billTypeList as $id => $billTypeId) {
            $billType = $this->getBillType($id);
            $billTypeId = $billType->getId();

            $opName = Blyn::app()->getActiveOperation()->getName();

            if ($opName == 'manage') {
                $billView = $this->getBillList($billType);
            } else {
                $billView = $this->getUserBillList($billType, NULL, NULL, 20);
            }
        }
        $this->updateControl->addRenderView('bill_list', 'bill_list_' . $opName, array(
            'billView' => $billView,
            'billType' => $billType,
            'billTypeId' => $billTypeId));
    }

    public function onShowManageBill($data = NULL) {
        return $this->onShowBillList($data);
    }

    public function getBillTable($billType = NULL) {

        if ($billType == self::BillType_All_Type) {
            return new BASpaceSheet('bill', BTreeTable::All_Owner);
        }

        if ($billType != NULL) {
            $billType = $this->getBillType($billType);
        } else {
            $billType = $this->getCurrentBillType();
        }

        if ($billType != NULL) {
            return new BASpaceSheet('bill', $billType);
        }
    }

    protected function getBillTypeRoot() {
        $category = new BACategory();
        $categoryRoot = $category->getRootNode();
        $billTypeRoot = $categoryRoot->getChild('billType');
        if ($billTypeRoot == NULL) {
            $billTypeRoot = $categoryRoot->addChild('billType');
        }
        return $billTypeRoot;
    }

    public function getCurrentBillType($data = NULL) {
        $billTypeId = $this->activeLink->getLinkVariable('billTypeId');

        if (is_numeric($billTypeId) && $billTypeId > 0) {
            //update value in context variable
            Blyn::app()->getUIManager()->getCurrentScreen()->addContextVariable('billTypeId', $billTypeId);
        } else {
            if ($billTypeId == NULL) {
                //try to find from context variable
                $billTypeId = Blyn::app()->getUIManager()->getCurrentScreen()->getContextVariable('billTypeId');
            }
        }

        if (is_numeric($billTypeId) && $billTypeId > 0) {
            $billType = new BACategory($billTypeId);
            return $billType;
        }
        return FALSE;
    }

    public function getBillType($nameOrId, $data = NULL) {

        if (is_numeric($nameOrId) && $nameOrId > 0) {
            return new BACategory($nameOrId);
        }

        if (is_string($nameOrId) && $nameOrId != NULL && $nameOrId != '') {
            $billTypeRoot = $this->getBillTypeRoot();
            $billType = $billTypeRoot->getChild($nameOrId);

            return $billType;
        }

        if ($nameOrId instanceof BACategory) {
            return $nameOrId;
        }


        //if not find any type, return first type defined
        $billTypeRoot = $this->getBillTypeRoot();
        $children = $billTypeRoot->getChildrenAsLeaf();
        if ($children != NULL)
            return $children[0];

        return FALSE;
    }

    /**
     * 
     * @param string formate, can be aliasList, nameList,objectList,arrayList
     * @param type $data
     * @return type
     */
    public function getBillTypeList($formate = 'aliasList', $data = NULL) {

        $billTypeRoot = $this->getBillTypeRoot();

        $children = $billTypeRoot->getChildrenAsLeaf();

        if (strtolower($formate) == 'objectlist') {
            return $children;
        }

        $list = array();

        foreach ($children as $id => $type) {

            if (strtolower($formate) == 'arraylist') {
                $item = array();
                $item['id'] = $id;
                $item['name'] = $typeName = $type->getName();
                $item['alias'] = $type->getValue();

                $tNames = explode('_', $typeName);
                $appName = $tNames[0];
                $item['appName'] = $appName;

                $list[$id] = $item;
            }
            if (strtolower($formate) == 'namelist') {
                $list[$id] = $type->getName();
            }
            if (strtolower($formate) == 'aliaslist') {
                $list[$id] = $type->getValue();
            }
        }

        return $list;
    }

    public function addBillType($name, $alias = null, $data = NULL) {

        $typeRoot = $this->getBillTypeRoot();

        if ($alias == NULL) {
            $alias = $name;
        }
        $type = $typeRoot->addChild(array('name' => $name, 'value' => $alias));
        if ($type != NULL) {
            $itemData = array();
            //check if exist type
            $itemData['billTypeId'] = $type->getId();
            $typeAttributeTable = new BAAttributeSheet($type);
            $list = $typeAttributeTable->getList(array('itemData' => $itemData));

            if ($list == NULL) {
                $list = $typeAttributeTable->getNewList();
            }

            $itemData['name'] = $name;
            $itemData['alias'] = $alias;
            if (is_array($data)) {
                $itemData+=$data;
            }

            //check if data changed, if not, no need to save
            $list2 = $typeAttributeTable->getList(array('itemData' => $itemData));
            if ($list2 == NULL)
                $list->addItems($itemData);

            return $type;
        }
        return FALSE;
    }

    /**
     * 获得交易列表, 默认按照时间从最新往前排练
     * @param type $billType
     * @param type $billData
     * @param type $limit
     * @return type
     */
    public function getBillList($billType = null, $billData = NULL, $limit = 20, $orderBy = 'billTime Desc') {

        if ($billType == NULL) {
            $billType = $this->getCurrentBillType();
        }

        $itemData = NULL;
        if (is_array($billData) && $billData != NULL) {
            $itemData = $billData;
        }

        if ($billType instanceof BEntity) {
            $billTable = new BASpaceSheet('bill', $billType);
        }

        if ($billType == self::BillType_All_Type) {
            $billTable = new BASpaceSheet('bill', BTreeTable::All_Owner);
        }

        if ($itemData != NULL)
            $billView = $billTable->getView(array('itemData' => $itemData, 'limit' => $limit, 'orderBy' => $orderBy));
        else {
            $billView = $billTable->getView(array('limit' => $limit, 'orderBy' => $orderBy));
        }

        return $billView;
    }

    public function addBill($itemData = NULL, $billId = NULL, $billType = NULL) {

        $bill = NULL;

        if ($billType == NULL) {
            $billType = $this->getCurrentBillType();
        } else {
            $billType = $this->getBillType($billType);
        }

        if ($billId == NULL) {
            $bill = $this->getCurrentBill();
            $billId = $bill->getId();
        }

        if ($itemData == NULL) {
            $itemData = array();
        }

        if (isset($itemData['billId'])) {
            $billId = $itemData['billId'];
            $bill = $billTable->getList(array('itemData' => array('billId' => $itemData['billId'])));
        }

        if ($billType != NULL) {

            //$billId = NULL;
            $billTable = new BASpaceSheet('bill', $billType);
            if (is_numeric($billId) && $billId > 0) {
                $bill = $billTable->getListById($billId);
                if ($bill->getName() != 'list' . $bill->getId()) {
                    $bill->name = 'list' . $bill->getId();
                    $bill->setOwner($this->getCurrentBillType());
                    $bill->save();
                }
            }

            if ($bill == NULL) {
                $bill = $billTable->getNewList();
            }

            if (!isset($itemData['billId'])) {
                $itemData['billId'] = 'bill' . $bill->getId();
            }

            $itemData['billTime'] = time();
            $itemData['billDate'] = date('Ymd');
            $itemData['billWeek'] = date('Y-W');
            $itemData['billMonth'] = date('Ym');
            $itemData['billQuarter'] = date('Y') . ceil(date('m') / 3);
            $itemData['billYear'] = date('Y');

            //计算出和上次交易的间隔时间
            $lastBill = $this->getLastUserBill($itemData, $billType);
            if ($lastBill != NULL) {
                $lastBillTimeItem = $lastBill->getItem('billTime');
                if ($lastBillTimeItem != NULL) {
                    $lastTime = $lastBillTimeItem->getValue();
                    $interval = time() - $lastTime;
                    $itemData['intervalTime'] = $interval;
                    $itemData['intervalHour'] = ceil($interval / 60 / 60);
                    $itemData['intervalDay'] = ceil($interval / 60 / 60 / 24);
                    $itemData['intervalWeek'] = ceil($interval / 60 / 60 / 24 / 7);
                }
            }

            if ($bill instanceof BTreeList) {
                $bill->addItems($itemData);
            }
        }

        return $bill;
    }

    public function getBill($itemData, $billType = NULL) {

        if (is_numeric($itemData) && $itemData > 0) {
            $billId = $itemData;
            $billTable = new BASpaceSheet('bill');
            return $billTable->getListById($billId);
        }

        if ($billType != NULL) {
            $billType = $this->getBillType($billType);
        }

        if ($billType == self::BillType_All_Type) {
            $billType = BTreeTable::All_Owner;
        }

        if ($billType == NULL) {
            $billType = $this->getCurrentBillType();
        }
        if ($billType != NULL) {
            if (is_array($itemData)) {
                $billTable = new BASpaceSheet('bill', $billType);
                return $billTable->getList(array('itemData' => $itemData));
            }
        }

        return FALSE;
    }

    public function getCurrentBill($data = NULL) {
        $billId = $this->activeLink->getLinkVariable('billId');

        if (is_numeric($billId) && $billId > 0) {
            //update value in context variable
            Blyn::app()->getActiveOperation()->addContextVariable('billId', $billId);
        } else {
            if ($billId == NULL) {
                //try to find from context variable
                $billId = Blyn::app()->getActiveOperation()->getContextVariable('billId');
            }
        }

        if (is_numeric($billId) && $billId > 0) {
            $bill = $this->getBill($billId);
            return $bill;
        }
        return FALSE;
    }

    /**
     * 获取用户的交易列表，默认产生20条记录，这个函数会首先找到用户注册的手机号
     * 然后和交易中使用的手机号匹配，查找出用户交易记录
     * @param type $billType
     * @param type $billData
     * @param type $userData
     * @param type $limit
     * @return type
     */
    public function getUserBillList($billType = NULL, $billData = NULL, $userData = NULL, $limit = 20) {

        $userCooker = new BAUserCooker();
        $userInfo = $userCooker->getUserInfo($userData);

        if (!is_array($billData)) {
            $billData = array();
        }

        $userBillList = array();

        if ($userInfo != NULL) {
            if ($userInfo->getItem('mobile') != NULL) {
                $mobile = $userInfo->getItem('mobile')->getValue();
                if ($mobile != NULL) {
                    $billData['mobile'] = $mobile;
                    $userBillList = $this->getBillList($billType, $billData, $limit);
                }
            }
        }

        return $userBillList;
    }

    /**
     * 获得用户最近的一条交易记录
     * @param type $userData
     * @param type $billType
     * @return boolean
     */
    public function getLastUserBill($userData = NULL, $billType = NULL) {

        //默认是所有交易类型中的最后一条交易记录
        if ($billType == NULL) {
            $billType = self::BillType_All_Type;
        }

        $uList = $this->getUserBillList($billType, NULL, $userData, 1);

        if ($uList != NULL) {
            return reset($uList);
        }

        return FALSE;
    }

    public static function getCurrencyData($data = NULL) {
        return array('rmb' => '人民币');
    }

    public static function getCurrencyUnitData($currency = 'rmb', $data = null) {

        if (strtolower($currency) == 'rmb') {
            return array(
                'fen' => '分',
                'jiao' => '角',
                'yuan' => '元'
            );
        }
    }

    public function showBillVoucherList($renderControl = NULL, $viewData = NULL) {

        $model = new BDynamicFormModel();

        $chooseVoucherField = 'media_chooseVoucher_add_bill_voucher';
        $model->addField($chooseVoucherField);

        if ($viewData == NULL) {
            $viewData = array();
        }
        $viewData['model'] = $model;
        $viewData['chooseVoucherField'] = $chooseVoucherField;

        if (!isset($viewData['billId'])) {
            $bill = $this->getCurrentBill();
            if ($bill != NULL) {
                $viewData['billId'] = $bill->getId();
            }
        } else {
            $billId = $viewData['billId'];
            $bill = $this->getBill($billId);
        }

        $voucherList = $this->getBillVoucherList($bill);
        $viewData['billVoucherList'] = $voucherList;

        $voucherCooker = new BAVoucherCooker();
        //$viewData['voucherListData'] = array();
        if (isset($viewData['mobile']) && $viewData['mobile'] != NULL) {
            $mobile = $viewData['mobile'];
            $voucherListData = $voucherCooker->getUserVoucherList('aliasList', array('mobile' => $mobile));
            $viewData['voucherListData'] = $voucherListData;
        }

        if ($renderControl != NULL) {
            $renderControl->addRenderView('billVoucherList', 'bill_voucher_list', $viewData);
            $renderControl->render();
            return;
        }

        $this->updateControl->addRenderView('billVoucherList', 'bill_voucher_list', $viewData);
    }

    public function getBillVoucherList($bill = null, $itemData = NULL) {

        if ($bill == NULL)
            $bill = $this->getCurrentBill();

        if (!is_array($itemData))
            $itemData = array();

        if ($bill != NULL) {
            $itemData['billId'] = $bill->getId();
            //$itemData['status'] = array(BAVoucherCooker::Voucher_Status_Waiting_Exchanged, BAVoucherCooker::Voucher_Status_Exchanged);
            //$itemData['addBillVoucherStartTime'] = '>' . (time() - 10 * 60); //10分钟可以

            $voucherCooker = new BAVoucherCooker();
            return $voucherCooker->getVoucherList($itemData, BTreeTable::All_Owner);
        }

        return array();
    }

    public function onAddBillVoucher() {

        $voucherData = $this->postManager->populatePostDataByIndex($this->postData, 'add_bill_voucher');

        $mobile = $this->activeLink->getLinkVariable('mobile');

        $voucherId = $voucherData['chooseVoucher'];

        $bill = $this->getCurrentBill();

        $voucherCooker = new BAVoucherCooker();

        if ($bill != NULL) {
            $voucher = $voucherCooker->getVoucher($voucherId);
            $itemData = array();
            $itemData['billId'] = $bill->getId();
            $itemData['addBillVoucherStartTime'] = time();
            if ($voucher instanceof BTreeList) {
                $voucher->addItems($itemData);
            }
        }

        $viewData = array();
        if ($mobile != NULL) {
            $viewData['mobile'] = $mobile;
        }
        $this->showBillVoucherList(NULL, $viewData);
    }

    public function onDeleteBillVoucher() {
        
    }

    protected function populateBillVoucherMoney($bill = null, $data = NULL) {

        if ($bill == NULL) {
            $bill = $this->getCurrentBill();
        }
        $voucherList = $this->getBillVoucherList($bill);

        $totalMoney = 0;

        $voucherCooker = new BAVoucherCooker();

        foreach ($voucherList as $voucher) {
            $voucherType = $voucherCooker->getVoucherTypeByVoucher($voucher);
            $vMoney = $voucherCooker->getVoucherTypeAttribute('money', $voucherType);
            //$voucherData = $voucher->getItemsInArray();
            //$vMoney = $voucher->getItem('money')->getValue();
            $totalMoney += $vMoney;
        }

        return $totalMoney;
    }

    protected function usedBillVouchers($bill = NULL) {
        if ($bill == NULL) {
            $bill = $this->getCurrentBill();
        }
        $voucherList = $this->getBillVoucherList($bill);

        foreach ($voucherList as $voucher) {
            if ($voucher instanceof BTreeList) {
                $voucher->addItem('status', BAVoucherCooker::Voucher_Used);
            }
        }

        return TRUE;
    }

    /**
     * 获取回头客的时间间隔发布图
     * 返回值是计算出的间隔值以及出现的频率，
     * 间隔值是以秒计算的时间间隔，需要自己换上成所需要显示的时间间隔
     * @param type $period
     * @param type $startTime
     * @param type $endTime
     * @param type $userData
     * @param type $billType
     * @return type return format like: array('intervalValue'=>'count')
     */
    /*
      public function getBillIntervalData($period = '3 months', $startTime = NULL, $endTime = null, $userData = NULL, $billType = NULL) {

      $billTable = NULL;

      if ($billType == self::BillType_All_Type) {
      //use to get data for all type
      $billTable = new BASpaceSheet('bill', BTreeTable::All_Owner);
      }

      if ($billType == NULL) {
      $billType = $this->getCurrentBillType();
      } else {
      $billType = $this->getBillType($billType);
      }

      if ($billType instanceof BEntity) {
      $billTable = new BASpaceSheet('bill', $billType);
      }

      $userInfoCooker = new BAUserCooker();
      if ($userData != NULL) {
      $oUserInfo = $userInfoCooker->getUserInfo($userData);
      if ($oUserInfo->getItem('mobile') != NULL) {
      $mobile = $oUserInfo->getItem(['mobile'])->getValue();
      }
      }

      $itemData = array();
      if (isset($mobile) && $mobile != NULL) {
      $itemData['mobile'] = $mobile;
      }

      $tStartTime = NULL;
      if ($startTime != NULL) {
      $tStartTime = strtotime($startTime);
      }

      if ($endTime != NULL) {
      $tEndTime = strtotime($endTime);
      if ($tEndTime > time()) {
      $tEndTime = time();
      }
      }

      if ($startTime == NULL && $endTime == NULL) {
      $tEndTime = time();
      }

      //根据计算的时间段长度计算开始时间和出结束时间
      if ($period != NULL) {
      //如果设置了开始时间，就用开始时间加上时间长度计算结束时间
      if ($tStartTime != NULL && $tEndTime == NULL) {
      $dtStartTime = new DateTime();
      $dtStartTime->setTimestamp($tStartTime);
      $dtPeriod = $dtStartTime->modify('+' . $period);
      $tPeriod = $dtPeriod->getTimeStamp();
      $tEndTime = $tPeriod;
      if ($tPeriod > time()) {
      $tEndTime = time();
      }
      }

      //根据结束时间和时间长度计算开始时间
      if ($tEndTime != NULL && $tStartTime == NULL) {
      $dtEndTime = new DateTime();
      $dtEndTime->setTimestamp($tEndTime);
      $dtPeriod = $dtEndTime->modify('-' . $period);
      $tPeriod = $dtPeriod->getTimeStamp();
      $tStartTime = $tPeriod;
      }
      }

      $itemData['billTime'] = array(
      '<' . $tEndTime, '>' . $tStartTime
      );

      $findText = 'billTime>' . $tStartTime . ' ' . 'billTime<' . $tEndTime;
      if (isset($mobile) && $mobile != NULL) {
      $findText.=' mobile=' . $mobile;
      }

      $interValueData = $billTable->getValueList('interval', NULL, $findText);

      return $interValueData;
      }
     * 
     */

    /**
     * 计算单位时间的访问次数的统计，返回单位时间客户买单次数的统计
     * 比如，获取月时间段的统计，参数输入为：
     * array(
     * 'timeSlotUnit'=>'month',//目前只支持 day,week,month,quarter,year这几个时间长度的统计
     * 'timeSlotCount'=>5,总共统计5个时间段,
     * 'endTime'=>'now'
     * }
     * 
     * 返回的值为
     * array(
     * 'billCount'=>'单位时间内买单次数',
     * 'billMonth'=>'买单的月份',
     * 'frequency'=>'所有客户中发生的频率'
     * }
     * 
     * 
     */
    public function getBillFrequencyData($periodData, $billType = NULL) {

        $billTable = $this->getBillTableFromBillType($billType);

        $timeData = BATimerCooker::populateTimePeriod($periodData);

        $findText = 'billTime>' . $timeData['startTime'] . ' billTime<' . $timeData['endTime'];

        $billPeriod = 'billMonth'; //default unit
        if (isset($periodData['timeSlotUnit'])) {
            $timeUnit = $periodData['timeSlotUnit'];
            if (strtolower($timeUnit) == 'day') {
                $billPeriod = 'billDay';
            }
            if (strtolower($timeUnit) == 'week') {
                $billPeriod = 'billWeek';
            }
            if (strtolower($timeUnit) == 'month') {
                $billPeriod = 'billIMonth';
            }
            if (strtolower($timeUnit) == 'quarter') {
                $billPeriod = 'billIQuarter';
            }
            if (strtolower($timeUnit) == 'year') {
                $billPeriod = 'billYear';
            }
        }

        $countValueList = $billTable->getValueList('count', NULL, $findText . ' groupBy=mobile,' . $billPeriod);
        $billPeriodValueList = $billTable->getValueList($billPeriod, NULL, $findText);

        $frequencyData = array();
        foreach ($countValueList as $countValue) {
            foreach ($billPeriodValueList as $billPeriodValue) {
                $itemContext['count'] = $countValue;
                $itemContext[$billPeriod] = $billPeriodValue;
                $frequency = $billTable->getCount(array('itemData' => $itemContext, 'groupBy' => 'mobile'));
                array_push($frequencyData, array(
                    $billPeriod => $billPeriodValue,
                    'accessCount' => $countValue,
                    'frequency' => $frequency
                ));
            }
        }

        return $frequencyData;
    }

    /**
     * 
     * @param type $periodData, 输入的值包括：
     * array(
     * 'startTime'=>...,可以不输入
     * 'endTime'=>...,如果不输入，就会取现在的值往前推
     * ‘timeSlotUnit'...,必须指定，可以为小时，天，星期，间隔时间将用这个
     * 指定值为单位。比如如果想统计多少天访问一次，那么 timeSlotUnit就应该
     * 是'day',同理，可以指定为 hour,week
     * 'timeSlotCount'=>...,STARTTIME 和 TIMESLOTCOUNT之中必须指定一个
     * 
     * @param type $billType
     * @return type, 返回值是 array('invernval','frequency'),即
     * 每一个间隔值出现的频率，比如 有些客户10天消费一次，有些20天一次，
     * 如果统计时间为一个月的话，返回值就是：
     * array(10=>60,20=>12)，表示统计的这个月，有间隔10天消费一次的次数为60次
     * 间隔20天消费一次的次数为12次
     * 反过来，也可以计算出有floor(60/（30/10))个客户消费了floor（30/10）次
     */
    public function getBillIntervaFrequencylData($periodData = NULL, $billType = NULL) {

        if ($billType == NULL) {
            $billType = self::BillType_All_Type;
        }

        $billTable = $this->getBillTableFromBillType($billType);

        if (is_array($periodData) && !isset($periodData['endTime'])) {
            $periodData['endTime'] = 'now';
        }

        $timeData = BATimerCooker::populateTimePeriod($periodData);

        $intervalPeriod = 'billMonth'; //default unit
        if (isset($periodData['timeSlotUnit'])) {
            $timeUnit = $periodData['timeSlotUnit'];
            if (strtolower($timeUnit) == 'hour') {
                $intervalPeriod = 'intervalHour';
            }
            if (strtolower($timeUnit) == 'day') {
                $intervalPeriod = 'intervalDay';
            }
            if (strtolower($timeUnit) == 'week') {
                $intervalPeriod = 'intervalWeek';
            }
        }

        $findText = 'billTime>' . $timeData['startTime'] . ' billTime<' . $timeData['endTime'];
        //$findText .=' groupBy=' . $intervalPeriod;

        return $billTable->getValueList($intervalPeriod, NULL, $findText);
    }

    /**
     * 根据计算时间段和统计时间段获得交易量以及交易次数
     * @param string $periodData           //计算时间段和统计时间段
     * 例如：
     * $periodData = array('timeSlotUnit'=>'Month','timeSlotCount'=>12,'startTime'=>'2015-3-10','endTime'=>'2016-3-10'');
     * 其中startTime和endTime可以不填
     * 正常情况下返回的是12个数组，每个数组含有“totalPayAmount”(总营业额)、“count”(交易总次数)
     * @return  array            //成功返回数组
     */
    public function getTobalBillByPeriod($periodData, $billType = NULL) {
        $billTable = $this->getBillTableFromBillType($billType);

        if (!isset($periodData['endTime'])) {
            $periodData['endTime'] = 'now';
        }

        $timeData = BATimerCooker::populateTimePeriod($periodData);

        $billPeriod = 'billMonth'; //default unit
        if (isset($periodData['timeSlotUnit'])) {
            $timeUnit = $periodData['timeSlotUnit'];
            if (strtolower($timeUnit) == 'day') {
                $billPeriod = 'billDate';
            }
            if (strtolower($timeUnit) == 'week') {
                $billPeriod = 'billWeek';
            }
            if (strtolower($timeUnit) == 'quarter') {
                $billPeriod = 'billQuarter';
            }
            if (strtolower($timeUnit) == 'year') {
                $billPeriod = 'billYear';
            }
        }

        $findContext = array();
        $findContext['itemData'] = array('billTime&' => array(
                '>' . $timeData['startTime'],
                '<' . $timeData['endTime']
        ));
        $findContext['groupBy'] = $billPeriod;
        $findContext['summary'] = array('totalPayAmount' => 'payAmount');

        $view = $billTable->getView($findContext);

        $finalData = array();
        foreach ($view as $id => $list) {
            //$aData = $list->getItemsInArray();
            $aData = array();
            $aData['totalPayAmount'] = $list->getRow()->getAttribute('totalPayAmount');
            $aData['count'] = $list->getRow()->getAttribute('count');
            $aData['items'] = $list->getItemsInArray();
            $finalData[$id] = $aData;
            //$billPeriodValue = $list->getItem($billPeriod)->getValue();
            //$totalPayAmount = $list->getItem('totalPayAmount')->getValue();
            //$finalData[$billPeriodValue] = $totalPayAmount;
        }
        return $finalData;
    }

    protected function getBillTableFromBillType($billType = NULL) {
        if ($billType == self::BillType_All_Type) {
            return new BASpaceSheet('bill', BTreeTable::All_Owner);
        }
        if ($billType != NULL) {
            $billType = $this->getBillType($billType);
        } else {
            $billType = $this->getCurrentBillType();
        }
        if ($billType instanceof BACategory) {
            return new BASpaceSheet('bill', $billType);
        }

        return FALSE;
    }

}
